﻿//  -------------------- iSharePoint -------------------- //
// 
//  Company:	IT Complex, LLC
//  Project:	Smart.Common
//  File name:	SqlQueryExecutor.cs
//  Developer:	Solomatov Igor
//  Created:	15.04.2012
// 
//  -------------------- iSharePoint -------------------- //

using System;
using System.Collections.Generic;
using System.Linq;

namespace Smart.Common.Entities
{
	/// <summary>
	/// Sql list query executor
	/// </summary>
	public class SqlQueryExecutor<TEntityType> : EntityFacadeQueryExecutor<TEntityType>
		where TEntityType : Entity
	{
		/// <summary>
		/// SqlQueryExecutor query executor
		/// </summary>
		public SqlQueryExecutor(EntityFacade<TEntityType> facade)
			: base(facade)
		{
		}

		/// <summary>
		/// Execute query and return list of entities
		/// </summary>
		public override IEntityList<TEntityType> Execute(int rowLimit)
		{
			return Execute(Query, rowLimit);
		}

		/// <summary>
		/// Execute query and return list of entities
		/// </summary>
		public override IEntityList<TEntityType> Execute(IQueryBuilder builder, int rowLimit)
		{
			if (builder != null)
			{
				var so = (MetaSqlObject)builder.Meta;

				if (so.ObjectType == SqlObjectType.SP)
				{
					var sqlBuilder = (IQueryBuilder<IEntityFacadeQueryExecutor<TEntityType>>)builder;
					var group = (SqlQueryBuilderWhere<IEntityFacadeQueryExecutor<TEntityType>>)sqlBuilder.Where;
					var facade = (SqlListService<TEntityType>)Facade.Service;

					var parameters = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase);

					foreach (var item in group.Children.Cast<SqlQueryBuilderConditionItem<IEntityFacadeQueryExecutor<TEntityType>>>())
					{
						if (item.Op != "=")
							throw new NotSupportedException("item.Op");

						var pName = so.FieldName(item.Field);
						var pValue = item.Value;

						parameters[pName] = pValue;
					}

					return facade.LoadEntities(parameters, rowLimit);
				}
			}

			var query = builder == null ? null : builder.FormatQuery();

			return Execute(query, rowLimit);
		}
	}
}